<template>
  <div>

    <el-tabs v-if="!formVisible" type="border-card">
      <el-tab-pane label="功能列表">
        <el-table size="small" :data="functions" highlight-current-row v-loading="loading" border element-loading-text="拼命加载中"
          style="width: 100%;">
          <el-table-column sortable prop="type" label="功能类型" width="100">
          </el-table-column>
          <el-table-column sortable prop="name" label="功能名称" width="180">
          </el-table-column>
          <el-table-column sortable prop="identifier" label="标识符" width="150">
          </el-table-column>
          <el-table-column sortable prop="dataTypeName" label="数据类型" width="100">
          </el-table-column>
          <el-table-column sortable prop="params" label="数据定义" width="200">
          </el-table-column>
          <el-table-column align="center" min-width="100">
            <template slot="header">
              <el-button @click="addFunction()" type="primary" size="mini" plain>新增功能</el-button>
            </template>
            <template slot-scope="scope">
              <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
              <el-popconfirm title="确认要删除该功能吗？" @confirm="deleteFunction(scope.$index, scope.row)" class="mg-left-10">
                <el-button slot="reference" size="mini" plain type="danger">删除</el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </el-tab-pane>
      <el-tab-pane label="TSL">
        <el-form>
          <vue-json-editor v-model="model" :showBtns="false" :mode="'code'" lang="zh" />
        </el-form>
      </el-tab-pane>
    </el-tabs>

    <el-tabs v-if="formVisible" type="border-card">
      <el-tab-pane :label="isAdd?'添加功能':'修改功能'">
        <el-form class="model-form" label-width="120px" :model="modelForm" ref="modelForm">
          <el-form-item label="功能类型">
            <el-radio-group :disabled="!isAdd" v-model="modelForm.type" size="mini">
              <el-radio-button label="property">属性</el-radio-button>
              <el-radio-button label="service">服务</el-radio-button>
              <el-radio-button label="event">事件</el-radio-button>
            </el-radio-group>
          </el-form-item>
          <div v-if="isSelectType('property')">
            <PropertyModel :property="modelForm.raw" :enumItems="enumItems" :boolItem="boolItem" :isProperty="true"></PropertyModel>
          </div>
          <div v-if="isSelectType('service')">
            <div>
              <el-form-item label="名称" prop="name">
                <el-input v-model="modelForm.name" size="small" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="标识符" prop="identifier">
                <el-input v-model="modelForm.identifier" size="small" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="输入参数">
                <ModelParams :modelParams="modelForm.raw.inputData"></ModelParams>
              </el-form-item>
              <el-form-item label="输出参数">
                <ModelParams :modelParams="modelForm.raw.outputData"></ModelParams>
              </el-form-item>
            </div>
          </div>
          <div v-if="isSelectType('event')">
            <div>
              <el-form-item label="名称" prop="name">
                <el-input v-model="modelForm.name" size="small" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="标识符" prop="identifier">
                <el-input v-model="modelForm.identifier" size="small" auto-complete="off"></el-input>
              </el-form-item>
              <el-form-item label="输出参数">
                <ModelParams :modelParams="modelForm.raw.outputData"></ModelParams>
              </el-form-item>
            </div>
          </div>
          <el-form-item>
          </el-form-item>
          <el-form-item>
            <el-button @click="cancelEdit">取消</el-button>
            <el-button @click="saveThingModel()" type="primary">保存</el-button>
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>


<script>
  import {
    ThingModelSave,
    GetThingModel,
    ParseProperty,
  } from '../../api/productApi'
  import PropertyModel from './PropertyModel.vue'
  import ModelParams from './ModelParams.vue'
  import vueJsonEditor from 'vue-json-editor'
  export default {
    name: 'ThingModel',
    props: {
      productKey: null
    },
    data() {
      return {
        loading: false, //是显示加载
        model: {},
        functions: [],
        formVisible: false,
        modelForm: {},
        enumItems: [{}],
        boolItem: {},
        isAdd: true
      }
    },
    // 注册组件
    components: {
      PropertyModel,
      ModelParams,
      vueJsonEditor
    },
    created() {},
    methods: {
      addFunction() {
        this.formVisible = true
        this.isAdd = true
        this.modelForm = {
          type: "property",
          identifier: "",
          name: "",
          raw: {
            name: "",
            identifier: "",
            type: "property",
            dataType: {
              specs: {}
            },
            inputData: [],
            outputData: [],
            enumItems: [],
            boolItem: {
              _true: "",
              _false: ""
            }
          }
        }
      },
      deleteFunction(index, row) {
        if (row.type == "property") {
          let index = this.model.properties.findIndex(p => {
            return p.identifier == row.identifier
          })
          this.model.properties.splice(index, 1)
        } else if (row.type == "service") {
          let index = this.model.services.findIndex(s => {
            return s.identifier == row.identifier
          })
          this.model.services.splice(index, 1)
        } else if (row.type == "event") {
          let index = this.model.events.findIndex(e => {
            return e.identifier == row.identifier
          })
          this.model.events.splice(index, 1)
        }

        this.submitThingModelChange()
      },
      handleEdit(index, row) {
        this.formVisible = true
        let tmpModel = JSON.parse(JSON.stringify(row));
        if (!tmpModel.raw.dataType) {
          tmpModel.raw.dataType = {};
        }
        tmpModel.raw.inputData = tmpModel.raw.inputData ? tmpModel.raw.inputData : [];
        tmpModel.raw.outputData = tmpModel.raw.outputData ? tmpModel.raw.outputData : [];

        let prop = tmpModel.raw
        if (prop.dataType.type == "enum") {
          let enumSpecs = []
          for (var p in prop.dataType.specs) {
            enumSpecs.push({
              name: prop.dataType.specs[p],
              value: p
            })
          }
          this.enumItems = enumSpecs
        } else if (prop.dataType.type == "bool") {
          this.boolItem = {
            _true: prop.dataType.specs["0"],
            _false: prop.dataType.specs["1"]
          }
        }

        this.modelForm = tmpModel;
        this.isAdd = false;
      },
      cancelEdit() {
        this.formVisible = false
      },
      isSelectType(type) {
        return type == this.modelForm.type
      },
      newProperty() {
        return ParseProperty(this.modelForm.raw, this.enumItems, this.boolItem)
      },
      saveThingModel() {
        if (this.isAdd) {
          if (this.modelForm.type == "property") {
            this.model.properties.push(this.newProperty());
          } else if (this.modelForm.type == "service") {
            this.model.services.push({
              identifier: this.modelForm.identifier,
              name: this.modelForm.name,
              inputData: this.modelForm.raw.inputData,
              outputData: this.modelForm.raw.outputData
            })
          } else if (this.modelForm.type == "event") {
            this.model.events.push({
              identifier: this.modelForm.identifier,
              name: this.modelForm.name,
              outputData: this.modelForm.raw.outputData
            })
          }
        } else {
          if (this.modelForm.type == "property") {
            let prop = this.newProperty()
            for (var i = 0; i < this.model.properties.length; i++) {
              if (this.model.properties[i].identifier == prop.identifier) {
                this.model.properties[i] = prop
              }
            }
          } else if (this.modelForm.type == "service") {
            this.model.services.forEach(s => {
              if (s.identifier == this.modelForm.identifier) {
                s.identifier = this.modelForm.identifier
                s.name = this.modelForm.name
                s.inputData = this.modelForm.raw.inputData
                s.outputData = this.modelForm.raw.outputData
              }
            })
          } else if (this.modelForm.type == "event") {
            this.model.events.forEach(s => {
              if (s.identifier == this.modelForm.identifier) {
                s.identifier = this.modelForm.identifier
                s.name = this.modelForm.name
                s.outputData = this.modelForm.raw.outputData
              }
            })
          }
        }

        this.submitThingModelChange()
      },
      submitThingModelChange() {
        this.loading = true
        ThingModelSave({
          productKey: this.productKey,
          model: JSON.stringify(this.model)
        }).then(() => {
          this.loading = false
          this.getThingModel()
          this.formVisible = false
        }, () => {
          this.loading = false
        })
      },
      getThingModel() {
        this.loading = true
        GetThingModel(this.productKey)
          .then(res => {
            this.loading = false
            res.model = res.model || {
              properties: [],
              events: [],
              services: []
            }
            res.model.properties = res.model.properties || []
            res.model.events = res.model.events || []
            res.model.services = res.model.services || []
            res.model = JSON.parse(JSON.stringify(res.model))

            this.model = res.model || {}
            let modelFuncs = [];
            this.model.properties.forEach(p => {
              let params = JSON.stringify(p.dataType.specs || "{}")
              modelFuncs.push({
                raw: p,
                type: "property",
                name: p.name,
                identifier: p.identifier,
                dataTypeName: p.dataType.type,
                params: params == '{}' ? '' : params
              })
            })
            this.model.events.forEach(e => {
              let output = {}
              e.outputData.forEach(p => {
                output[p.identifier] = p.name
              })
              modelFuncs.push({
                raw: e,
                type: "event",
                name: e.name,
                identifier: e.identifier,
                dataTypeName: '-',
                params: JSON.stringify(output)
              })
            })
            this.model.services.forEach(s => {
              let input = {};
              (s.inputData || []).forEach(p => {
                input[p.identifier] = p.name
              })
              let output = {};
              (s.outputData || []).forEach(p => {
                output[p.identifier] = p.name
              })
              modelFuncs.push({
                raw: s,
                type: "service",
                name: s.name,
                identifier: s.identifier,
                dataTypeName: '-',
                params: ('输入:' + JSON.stringify(input) +
                  ",输出:" + JSON.stringify(output))
              })
            })

            this.functions = modelFuncs
          }, () => {
            this.loading = false
          })
      }
    },
    watch: {
      immediate: true,
      productKey: function(newVal) {
        if (newVal == "") {
          return;
        }
        this.productKey = newVal
        this.formVisible = false
        this.getThingModel()
      }
    }
  }
</script>

<style>
  .model-form .line {
    text-align: center;
  }
</style>
